package com.gym.common.redis.resource;

import java.util.List;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;

/**
 * 缓存工具：提供Jedis的实例
 * 
 */
@Repository
public class JedisCacheUtil {

	private static final Logger logger = LoggerFactory.getLogger(JedisCacheUtil.class);

	@Autowired
	private List<JedisPool> jedisCachePoolList;

	private final byte[] lock = new byte[0];
	private volatile int nextPoolCount = 0;
	private volatile JedisPool currentPool;

	public JedisCacheUtil() {
	}

	/**
	 * @return the pool
	 */
	private JedisPool getPool() {
		/**
		 * 如果当前pool为空，则选择pool1。
		 */
		if (currentPool == null) {
			synchronized (lock) {
				if (currentPool == null) {
					if (jedisCachePoolList != null && !jedisCachePoolList.isEmpty()) {
						int poolCount;
						poolCount = jedisCachePoolList.size();
						nextPoolCount = (nextPoolCount + 1) % poolCount;
						currentPool = jedisCachePoolList.get(nextPoolCount);
						Jedis jedis = null;
						try {
							jedis = getPool().getResource();
							jedis.set("a1key1a", "value");
							returnJedis(jedis);

						} catch (Exception e) {
							if (jedis != null) {
								returnJedis(jedis);
							}
							logger.error("getPool Exception", e);
							currentPool = null;
						}
						logger.info("Jedis Pool switch master to {}", nextPoolCount);
					}
				}
			}
		}
		return currentPool;
	}

	/**
	 * 获取Jedis连接
	 * 
	 * @return
	 */
	public Jedis getJedis() throws TimeoutException{
		Jedis jedis = null;
		int tryCount = 0;
		int poolListSize = (jedisCachePoolList == null) ? 0 : (jedisCachePoolList.size() + 2);
		while (jedis == null && tryCount < poolListSize) {
			try {
				if (getPool() != null) {
					jedis = getPool().getResource();
				}
			} catch (JedisConnectionException jce) {
				currentPool = null;
				logger.info("Jedis Pool should switch master");
			} catch (JedisDataException jde) {
				logger.error("JedisDataException", jde);
				currentPool = null;
			}
			tryCount++;
		}
		if(jedis==null){
			throw new TimeoutException("getJedis.error master is not connection");
		}
		return jedis;
	}

	/**
	 * 归还/释放Jedis连接
	 * 
	 * @param jedis
	 */
	public void returnJedis(Jedis jedis) {
		try {
			if (jedis != null) {
				getPool().returnResource(jedis);
			}
		} catch (Exception e) {
			 //nothing to do
		}
	}

}
